﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using Medianamik.Core;
using Medianamik.Core.Profile;
using Medianamik.Core.Querying;
using Medianamik.Core.Security;
using Medianamik.Globalization;
using Medianamik.UI.Controls;
using Telerik.Web.UI;
using System.Linq;
using Medianamik.Core.Sugar;

namespace Medianamik.UI.SecurityManagement
{
    public partial class UserList : BaseModuleListPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Grid.ItemDataBound += Grid_ItemDataBound;

            if (!IsPostBack)
            {
                BindGroups();
                Grid.PageSize = GetQueryStringValue<int?>("nb") ?? 20;
                Grid.CurrentPageIndex = (GetQueryStringValue<int?>("p") ?? 1 - 1) * Grid.PageSize;
                Form.DefaultButton = RefreshButton.UniqueID;
            }
        }

        protected override string ReturnUrl
        {
            get { return "/medianamik/securitymanagement/userlist.aspx"; }
        }

        protected override void GridNeedDataSource(object source, GridNeedDataSourceEventArgs e)
        {
            Grid.DataSource = GetUserProfiles(GetGroups(), FilterBox.Text, UserStatus.All);
        }

        protected void FilterByGroup(object sender, EventArgs e)
        {
            Grid.Rebind();
        }

        protected void FilterList(object sender, EventArgs e)
        {
            Grid.Rebind();
        }

        protected override Guid RootNodeId
        {
            get { return MedianamikModules.SecurityManagement; }
        }

        protected override RadGrid Grid
        {
            get { return UserGrid; }
        }

        protected void Grid_ItemDataBound(object source, GridItemEventArgs e)
        {
            if ((e.Item.ItemType == GridItemType.Item || e.Item.ItemType == GridItemType.AlternatingItem) &&
                e.Item.DataItem != null)
            {
                var user = e.Item.DataItem as UserProfile;

                if (user.UserName.Equals(MedianamikUser.UserName, StringComparison.OrdinalIgnoreCase))
                {
                    var editButton = (LockButton)e.Item.FindControl("EditButton");
                    editButton.Enabled = false;

                    var deleteButton = (LockButton)e.Item.FindControl("DeleteButton");
                    deleteButton.Enabled = false;
                    
                }
            }

        }

        protected override bool DestroyOnDelete
        {
            get
            {
                return true;
            }
        }

        protected override UpdatePanel GridUpdatePanel
        {
            get { return UsersUpdatePanel; }
        }

        protected override string ManagementURL
        {
            get { return "editUser.aspx"; }
        }

        protected override GridOptions GridOptions
        {
            get
            {
                return GridOptions.None;
            }
        }

        public IEnumerable<UserProfile> GetUserProfiles(IEnumerable<string> groups,
            string usernameFilter, UserStatus statusFilter)
        {
            var deserializedProfiles = GetProfiles(groups, statusFilter).ToList();

            var userProfiles = new HashSet<UserProfile>();

            foreach (var profile in deserializedProfiles)
            {
                //profile.DeserializeProfileNodeProperties();
                var user = Membership.GetUser(profile.UserId, false);

                if (user != null)
                {
                    userProfiles.Add(new UserProfile(profile.ID, profile.UserId, user.UserName, profile.FullName,
                        user.IsApproved, profile.LastLoginDate, profile.SubscriptionDate));
                }
            }

            if (usernameFilter.Length > 0)
                return userProfiles.Where(u =>
                    u.UserName.Contains(usernameFilter, StringComparison.OrdinalIgnoreCase) ||
                    u.FullName.Contains(usernameFilter, StringComparison.OrdinalIgnoreCase));

            return userProfiles.OrderBy(x => x.FullName);
        }

        private IEnumerable<ProfileNode> GetProfiles(IEnumerable<string> groups, 
            UserStatus statusFilter)
        {
            var profileQuery = new Query()
                .Where(n => n.NodeTypeID, Comparison.Equal, MedianamikTypes.MedianamikProfile);

            if (groups.Count() > 0 || statusFilter != UserStatus.All)
            {
                var users = SecurityManager.GetUsersInGroups(groups);

                if (users.Count() > 0)
                    profileQuery.Where(MedianamikProperties.ProfileUser, Comparison.In, users);
                else
                    return Enumerable.Empty<ProfileNode>();
            }
            else if (groups.Count() == 0 && !MedianamikUser.IsSuperAdmin)
                return Enumerable.Empty<ProfileNode>();

            return profileQuery.AsQuery<ProfileNode>().Execute();
        }

        private IEnumerable<string> GetGroups()
        {
            var groups = new HashSet<string>();

            if (Groups.SelectedIndex > 0)
                groups.Add(Groups.SelectedValue);
            else if (!MedianamikUser.IsSuperAdmin)
                MedianamikUser.Groups.GetAllAllowedGroups(MedianamikUserProfile)
                    .Select(g => g.Name).ForEach(g => groups.Add(g));

            return groups;
        }

        private void BindGroups()
        {
            Groups.DataTextField = "Text";
            Groups.DataValueField = "Value";


            Groups.DataSource = MedianamikUser.Groups.GetAllAllowedGroups(MedianamikUserProfile).Select(g => new
            {
                Text = g.TranslatedName,
                Value = g.Name
            }).OrderBy(a => a.Text);

            Groups.DataBind();
            Groups.Items.Insert(0,
                Translator.Translate("Medianamik_SecurityManagement", "AllUsers"));
        }

        protected string GetUserGroups(Guid userId)
        {
            var result = "&nbsp;";
            var user = Membership.GetUser(userId);

            if (user != null)
            {
                var test = ((MedianamikUser)user).Groups
                    .OrderBy(g => g.Depth)
                    .Select(g => g.TranslatedName).ToString(", ")
                    .TrimStart(',').TrimEnd(',').TrimStart(' ').TrimEnd(' ');

                if (test.Length > 0)
                    result = test;
            }

            return result;
        }

        public class UserProfile : IEntity
        {
            public UserProfile(Guid profileId, Guid userId, string userName, string fullName, bool isActive,
                DateTime? lastLoginDate, DateTime? subscriptionDate)
            {
                _id = profileId;
                _userId = userId;
                _userName = userName;
                _subscriptionDate = subscriptionDate;
                _lastLoginDate = lastLoginDate;
                _isApproved = isActive;
                _fullName = fullName;
            }

            private Guid _id;
            public Guid ID
            {
                get { return _id; }
            }

            private readonly Guid _userId;
            public Guid UserId
            {
                get { return _userId; }
            }

            private readonly string _userName;
            public string UserName
            {
                get { return _userName; }
            }

            private readonly string _fullName;
            public string FullName
            {
                get { return _fullName; }
            }

            private readonly bool _isApproved;
            public bool IsApproved
            {
                get { return _isApproved; }
            }

            private readonly DateTime? _lastLoginDate;
            public DateTime? LastLoginDate
            {
                get { return _lastLoginDate; }
            }

            private readonly DateTime? _subscriptionDate;
            public DateTime? SubscriptionDate
            {
                get { return _subscriptionDate; }
            }
        }
    }
}
